package views.roller
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	import gs.TweenLite;
	import gs.easing.Back;
	import gs.easing.Cubic;
	
	[Event(name="complete",type="flash.events.Event")]
	
	public class RollerView extends Sprite
	{
		public var items:Vector.<RollItem>;

		public var isExpand:Boolean;
		public var isMoving:Boolean;
		
		private const EXPAND_DURATION:Number = 0.3;
		private const EXPANT_DELAY:Number = 0.1;
		
		public function RollerView()
		{
		}
		
		public function addItems(items:Vector.<RollItem>):void
		{
			while(numChildren > 0)
				removeChildAt(0);
			
			isExpand = false;
			isMoving = false;
			this.items = items;
			
			for each(var item:RollItem in items)
			{
				var unfoldMatrix:Matrix = new Matrix;
				unfoldMatrix.tx = item.origin.x;
				unfoldMatrix.ty = item.origin.y;
				
				var a:Number;
				var b:Number;
				var c:Number;
				if(item.roller[1].x - item.roller[0].x != 0)
				{
					var k:Number =  (item.roller[1].y - item.roller[0].y) / (item.roller[1].x - item.roller[0].x);
					a = k;
					b = -1;
					c = item.roller[0].y - k * item.roller[0].x;
				}else{
					a = 1;
					b = 0;
					c = -1 * item.roller[0].x;
				}
				
				var foldMatrix:Matrix = new Matrix;
				foldMatrix.a = (b*b - a*a) / (a*a + b*b);
				foldMatrix.c = -2*a*b / (a*a + b*b);
				foldMatrix.tx = -2*a*c / (a*a + b*b);
				
				foldMatrix.b = -2*a*b / (a*a + b*b);
				foldMatrix.d =  (a*a - b*b) / (a*a + b*b);
				foldMatrix.ty = -2*b*c / (a*a + b*b);
				
				item.unfoldMatrix = unfoldMatrix;
				item.foldMatrix = unfoldMatrix.clone();
				item.foldMatrix.concat(foldMatrix);
				
				item.view.transform.matrix = item.foldMatrix;
				item.view.alpha = 0;
				item.view.visible = false;
				addChildAt(item.view,0);
				
				if(item.view is Sprite)
					(item.view as Sprite).addEventListener(MouseEvent.CLICK,itemClickHandler);
			}
		}
		
		private function itemClickHandler(evt:MouseEvent):void
		{
			if(isMoving)
				return;
			
			var view:DisplayObject = evt.currentTarget as DisplayObject;
			for each(var item:RollItem in items)
			{
				if(item.view == view)
				{
					if(item.callback is Function)
						item.callback.call(null,item);
					break;
				}
			}
			
		}
		
		public function expand(animated:Boolean = true):void
		{
			if(isExpand || isMoving)
				return;
			
			isMoving = true;
			var index:int = 0;
			for each(var item:RollItem in items)
			{
				item.view.visible = true;
				if(animated)
				{
					item.view.alpha = 0;	
					TweenLite.to(item.view,EXPAND_DURATION,{delay:EXPANT_DELAY * index,alpha:1,ease:Cubic.easeOut});	
					
					item.effectingMatrix =  item.foldMatrix.clone();
					var objTween:Object = {delay:EXPANT_DELAY * index,a:item.unfoldMatrix.a,b:item.unfoldMatrix.b,c:item.unfoldMatrix.c,
						d:item.unfoldMatrix.d,tx:item.unfoldMatrix.tx,ty:item.unfoldMatrix.ty,
						ease:Cubic.easeOut,
						onUpdate:function(item:RollItem):void{item.view.transform.matrix = item.effectingMatrix.clone();},
						onUpdateParams:[item]};
					
					if(index >= items.length - 1)
						objTween["onComplete"] = function():void{isExpand = true;
							isMoving = false;
							dispatchEvent(new Event(Event.COMPLETE));};
					TweenLite.to(item.effectingMatrix,EXPAND_DURATION,objTween);
				}else{
					item.view.alpha = 1;
					item.view.transform.matrix = item.unfoldMatrix.clone();
					isExpand = true;
					isMoving = false;
				}
				index ++;
			}
		}
		
		public function rollback(animated:Boolean = true):void
		{
			if(!isExpand || isMoving)
				return;
			
			isMoving = true;
			for(var index:int = items.length - 1;index >= 0; index--)
			{
				var item:RollItem = items[index];
				
				if(animated)
				{
					item.view.visible = true;
					item.view.alpha = 1;
					TweenLite.to(item.view,EXPAND_DURATION,{delay:EXPANT_DELAY * (items.length - 1 - index),alpha:0,ease:Cubic.easeIn});	
					
					item.effectingMatrix =  item.unfoldMatrix.clone();
					var objTween:Object = {delay:EXPANT_DELAY * (items.length - 1 - index),a:item.foldMatrix.a,b:item.foldMatrix.b,c:item.foldMatrix.c,
						d:item.foldMatrix.d,tx:item.foldMatrix.tx,ty:item.foldMatrix.ty,
						ease:Cubic.easeIn,
						onUpdate:function(item:RollItem):void{item.view.transform.matrix = item.effectingMatrix.clone();},
						onUpdateParams:[item],onCompleteParams:[item]};
					
					if(index <= 0)
						objTween["onComplete"] = function(item:RollItem):void{item.view.visible = false;
							isExpand = false;
							isMoving = false;
							dispatchEvent(new Event(Event.COMPLETE));};
					else
						objTween["onComplete"] = function(item:RollItem):void{item.view.visible = false};
					
					TweenLite.to(item.effectingMatrix,EXPAND_DURATION,objTween);
				}else{
					item.view.alpha = 0;
					item.view.visible = false;
					item.view.transform.matrix = item.foldMatrix.clone();
					isExpand = false;
					isMoving = false;
				}
			}
			
		}
		
	}
}